
TinyEditor.editors = new Array();

TinyEditor.globalLock = false;

TinyEditor.getEditor = function ( id )
{
  return eval( "TinyEditor.editors['" + id + "']" );
}

function TinyEditor ( id, styleSheet )
{
  this.id = id;
  this.frameName = id + "_frame";
  this.maskName = id + "_mask";
  this.dom = YAHOO.util.Dom;
  this.styleSheetHref = styleSheet;
  this.textareaEl = null;
  this.lastClicked = 0;
    
  this.textChanged = new YAHOO.util.CustomEvent("textChanged", this); 
  this.saveCall = new YAHOO.util.CustomEvent("saveCall", this);

  eval( "TinyEditor.editors['" + id + "'] = this;" );
}

TinyEditor.prototype.init = function ()
{
  this.init( false );
}

TinyEditor.prototype.init = function ( forceDesignMode )
{  
    this.textareaEl = this.dom.get( this.id );
    var text = this.textareaEl.value;
    var parent = this.textareaEl.parentNode;

    var ediv = document.createElement( "DIV" );
    ediv.setAttribute( "id", this.id + "_parent" );
    ediv.setAttribute( "style", "position:relative;" );

    var iframe = document.createElement( "iframe" );
    iframe.setAttribute( "id", this.frameName );
    iframe.setAttribute( "width", "100%" );
    iframe.setAttribute( "height", "100%" );
    iframe.setAttribute( "class", this.textareaEl.getAttribute( "class" ) );

    //parent.replaceChild( iframe, this.textareaEl );
    ediv.appendChild( iframe );

    if ( forceDesignMode && text.length > 0 ) {
      text = this.undoLinks( text );
    }

    var mask = document.createElement( "div" );
    mask.setAttribute( "id", this.maskName );
    mask.setAttribute( "style", "position:absolute; top:0px; left:0px; width:100%; height:100%;" );
    
    ediv.appendChild( mask );

    parent.replaceChild( ediv, this.textareaEl );

    var doc = iframe.contentWindow.document;
    doc.open();
    doc.write( "<html><head><link tyle='text/css' rel='stylesheet' href='" + 
               this.styleSheetHref + "'></head><body>" );
    doc.write( text );
    doc.write( "</body></html>" );
    doc.close();

    YAHOO.util.Event.addListener( doc, 'keydown', this.handleKeyDown, this, true ); 
    YAHOO.util.Event.addListener( doc, 'click', this.handleClick, this, true );
    YAHOO.util.Event.addListener( mask, 'mouseover', this.handleMouseOver, this, true );
    YAHOO.util.Event.addListener( doc, 'mouseout', this.handleMouseOut, this, true );
}

TinyEditor.prototype.destroy = function ()
{
  var iframe = this.dom.get( this.frameName );
  var parent = iframe.parentNode;

  parent.replaceChild( this.textareaEl, iframe );
}  

TinyEditor.prototype.handleMouseOver = function ( evt )
{
  if ( !TinyEditor.globalLock ) {
    var mask = new YAHOO.util.Element( this.maskName );
    mask.setStyle( "visibility", "hidden" );
  }
}

TinyEditor.prototype.handleMouseOut = function ( evt )
{
  var mask = new YAHOO.util.Element( this.maskName );
  mask.setStyle( "visibility", "visible" );
}

TinyEditor.prototype.handleClick = function ( evt )
{
  //double click to turn on design mode
  var now = ( new Date() ).getTime();
  if ( now - this.lastClicked < 300 ) {
    //turn on design mode
    this.unlock();
  }

  this.lastClicked = now;
}

TinyEditor.prototype.handleKeyDown = function ( evt )
{
  if ( this.dom.get( this.frameName ).contentDocument.designMode == 'on' ) {
    if ( evt.keyCode == 66 && evt.ctrlKey ) {
      this.toggleBold();
      YAHOO.util.Event.preventDefault( evt );
    }
    else if ( evt.keyCode == 73 && evt.ctrlKey ) {
      this.toggleItalic();
      YAHOO.util.Event.preventDefault( evt );
    }
    else if ( evt.keyCode == 85 && evt.ctrlKey ) {
      this.toggleUnderline();
      YAHOO.util.Event.preventDefault( evt );
    }
    else if ( evt.keyCode == 83 && evt.ctrlKey ) {
      this.saveCall.fire();
      YAHOO.util.Event.preventDefault( evt );
    }
    else if ( evt.keyCode == 8 ) {
      //delete key
      this.textChanged.fire();
    }
    else if ( evt.keyCode >= 32 && evt.keyCode <= 127 ) {
      this.textChanged.fire();
    }
  }
}

TinyEditor.prototype.undoLinks = function ( data )
{
    var newData = data;

    var s = -1;
    while ( ( s = newData.indexOf( "<a ", s ) ) > -1 )
    {
      var hs = newData.indexOf( "href=\"", s );
      var he = newData.indexOf( "\"", hs + 6 );
      
      var url = newData.substring( hs + 6, he );

      var e = newData.indexOf( ">", s );
      
      var et = newData.indexOf( "</a>", e );      

      var name = newData.substring( e + 1, et );
      
      var linkRep = "{" + url + "}[" + name + "]";

      newData = newData.substring( 0, s ) + linkRep + newData.substring( et + 4 );

      s = s + linkRep.length;
    }

    return newData;
}

TinyEditor.prototype.unlock = function ()
{
  var mask = new YAHOO.util.Element( this.maskName );
  mask.setStyle( "visibility", "hidden" );

  var doc = this.dom.get( this.frameName ).contentDocument;

  var body = doc.getElementsByTagName( "body" )[0];

  if ( body ) {
    var txt = body.innerHTML;
    body.innerHTML = this.undoLinks( txt );
  }
  else {
    //YIKES!? Kind of scary but seems to work.
    //Firefox needs this for turning on designmode for newly created iframe
    var self = this;
    setTimeout( function () { self.unlock(); }, 100 );
    return false;
  }

  doc.designMode = 'on';
}

TinyEditor.prototype.lock = function ()
{
  var doc = this.dom.get( this.frameName ).contentDocument; 

  doc.designMode = 'off';

  doc.getElementsByTagName( "body" )[0].innerHTML = this.getValue();

  var mask = new YAHOO.util.Element( this.maskName );
  mask.setStyle( "visibility", "visible" );
}

TinyEditor.prototype.focus = function ()
{
  this.dom.get( this.frameName ).contentWindow.focus();  
}

TinyEditor.prototype.toggleBold = function () 
{
  this.dom.get( this.frameName ).contentDocument.execCommand("bold", false, null);
}

TinyEditor.prototype.toggleItalic = function () 
{
  this.dom.get( this.frameName ).contentDocument.execCommand("italic", false, null);
}

TinyEditor.prototype.toggleUnderline = function ()
{
  this.dom.get( this.frameName ).contentDocument.execCommand("underline", false, null);
}

TinyEditor.prototype.hasText = function ()
{
  var txt = this.dom.get( this.frameName ).contentDocument.getElementsByTagName( "body" )[0].innerHTML;
  return ( txt != '' && txt != '<br>' );
}

TinyEditor.prototype.getValue = function ()
{
  function replaceURLs ( data ) 
  {
    var newData = data;

    var s = -1;
    while ( ( s = newData.indexOf( "{http://", s ) ) > -1 )
    {
      var e = newData.indexOf( "}", s );

      var url = newData.substring( s + 1, e );

      var name = url;
      if ( newData.charAt( e + 1 ) == '[' ) {
        var ne = newData.indexOf( "]", e );
	name = newData.substring( e + 2, ne );
	e = ne;
      }

      var link = "<a target=_blank class=\"noteLink\" href=\"" + url + "\">" + name + "</a>";

      newData = newData.substring( 0, s ) + link + newData.substring( e + 1 );

      s = s + link.length;
    }  

    return newData;
  }

  var txt = this.dom.get( this.frameName ).contentDocument.getElementsByTagName( "body" )[0].innerHTML;  
  
  return replaceURLs( txt ); 
}

TinyEditor.prototype.hide = function ()
{
  this.dom.get( this.frameName ).style.visibility = "hidden";
}

TinyEditor.prototype.show = function ()
{
  this.dom.get( this.frameName ).style.visibility = "visible";
}


